home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / gprim / discgrp / dgenum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-30  |  5.0 KB  |  222 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "wa.h"
  4. #include "vec4.h"
  5. #include "dgflag.h"
  6. #include "enum.h"
  7. #include "color.h"
  8. #include "3d.h"
  9. #include "ooglutil.h"
  10. #include "discgrpP.h"
  11.  
  12.  
  13.         static DiscGrp *mydg;
  14.         static ColorA white = {1,1,1,.75};
  15.         static DiscGrpEl grpel;
  16.     static Transform mlist[128];
  17.     static int (*constraintfn)();
  18.     int check_big = 1,     /* this is currently never non-zero */
  19.         check_new = 1,     /* ditto */
  20.         have_matrices = 1,
  21.         metric = DG_HYPERBOLIC,
  22.         stringent = 0;
  23.     int 
  24.         long_cnt = 0,
  25.         same_cnt = 0,
  26.         far_cnt = 0, 
  27.         print_cnt = 0, 
  28.         store_cnt = 0;
  29.     static int numchunks = 1;
  30.     static int ngens = 0;
  31.     int debug = 0;
  32.     static char symbollist[64];
  33.     static void get_matrices();
  34.  
  35. int
  36. getindex(c)
  37. char c;
  38. {
  39.     int i;
  40.     for (i=0; i<ngens; ++i)
  41.     if (symbollist[i] == c) return(i);
  42.     return(-1);
  43. }
  44.  
  45. static
  46. word_to_mat(word, mat1)
  47. char *word;
  48. Transform mat1;
  49. {
  50.     int length, i, index;
  51.     /*printf("# %s\n",word); */
  52.     TmIdentity(mat1);
  53.  
  54.     for (i=0; word[i] != 0; ++i)
  55.     {
  56.     index = getindex(word[i]);
  57.     if (index < 0)    {
  58.         printf("Bad symbol\n");
  59.         return;
  60.         }
  61.     TmConcat(mat1, mlist[index], mat1);
  62.     }
  63. }
  64.  
  65. static int 
  66. is_big_and_new(DiscGrpEl *dgel)
  67. {
  68.     int is_big=0, is_n = DG_CONSTRAINT_NEW;
  69.     if (check_new)    is_n = is_new(dgel->tform);
  70.     if (is_n) {
  71.     is_big = constraintfn(dgel);
  72.     if (is_big & DG_CONSTRAINT_LONG) long_cnt++;
  73.     if (is_big & DG_CONSTRAINT_PRINT) print_cnt++;
  74.     if (is_big & DG_CONSTRAINT_STORE) store_cnt++;
  75.     if (is_big & DG_CONSTRAINT_TOOFAR) far_cnt++;
  76.     }
  77.     else same_cnt++;
  78.     return(is_big | is_n );
  79. }    
  80.  
  81.  
  82. static int
  83. process(DiscGrpEl *dgel, int stacking)
  84. {
  85.     Transform mat;
  86.     register int is_ok;
  87.  
  88.         if (have_matrices)        {
  89.             is_ok = is_big_and_new(dgel);
  90.         /* remember that only NEW and PRINT are required to be here */
  91.             if (is_ok & DG_CONSTRAINT_NEW )    {
  92.          if (!(is_ok & DG_CONSTRAINT_LONG))    {
  93.           if (is_ok & (DG_CONSTRAINT_STORE | DG_CONSTRAINT_PRINT))     {
  94.               if (check_new)    {
  95.                 insert_mat(dgel->tform);
  96.                   /* and put it on the stack */
  97.                   if (stacking) push_new_stack(dgel->word);
  98.                 }
  99.                   if (is_ok & DG_CONSTRAINT_PRINT)   enumpush(dgel);
  100.               }
  101.           }
  102.          }
  103.             }
  104.          return(is_ok);
  105. }
  106.  
  107. static int
  108. enumerate(int state, int depth, DiscGrpEl *dgel)
  109. {
  110.     register int i, newstate, pval;
  111.     Transform mat;
  112.     char wword[64];
  113.  
  114.     if ( ! ((pval = process(dgel, 0)) & DG_CONSTRAINT_STORE)) return 0;
  115.     if (pval & DG_CONSTRAINT_MAXLEN)    return 0;
  116.     if (depth > MAXDEPTH) return 0;
  117.  
  118.     for (i=1; i<mydg->fsa->ngens; ++i)
  119.         {
  120.         newstate = mydg->fsa->action[state][i];
  121.         if ( newstate != mydg->fsa->fail)
  122.         {
  123.             dgel->word[depth] = mydg->fsa->genlist[i-1][0];
  124.             dgel->word[depth+1] = 0;    /* null-terminate */
  125.         word_to_mat(dgel->word, dgel->tform);
  126.             enumerate(newstate, depth+1, dgel);
  127.            }
  128.         }
  129. }
  130.  
  131. static int
  132. dumb_enumerate(int depth, DiscGrpEl *dgel)
  133. {
  134.     register int i, j, l, stacking;
  135.     Transform mat;
  136.     char *word, wword[64];
  137.     extern char  *pop_old_stack();
  138.  
  139.     init_stack();
  140.     process(dgel, 1);
  141.     for (j = 0; j < MAXDEPTH ; ++j)
  142.         {
  143.         make_new_old();
  144.         /* are we interested in his descendents ? */
  145.         while ( (word = pop_old_stack()) != NULL)    {
  146.         /* these words have length j */
  147.         strcpy(dgel->word, word);
  148.             for (i=0; i<ngens; ++i)
  149.                 {
  150.                 dgel->word[j] = symbollist[i];
  151.                 dgel->word[j+1] = 0;    /* null-terminate */
  152.             word_to_mat(dgel->word, dgel->tform);
  153.             process(dgel, 1);
  154.                 }
  155.         }
  156.         }
  157. }    
  158.  
  159.     static char emptyword[64] = "";
  160. /* 
  161.  * hack together an enumerate routine
  162.  */
  163.  
  164. DiscGrpElList *
  165. DiscGrpEnum(DiscGrp *discgrp, int (* constraint)(void) )
  166. {
  167.     DiscGrpElList *enum_list = OOGLNewE(DiscGrpElList, "DiscGrpEnum");
  168.     extern DiscGrpEl *enumgetstack();
  169.     DiscGrpEl dgel;
  170.  
  171.     /* initialize the local variables */
  172.     constraintfn = constraint;
  173.     have_matrices = 1;
  174.     same_cnt = 0;
  175.     far_cnt = 0;
  176.     print_cnt = 0;
  177.     store_cnt = 0;
  178.     long_cnt = 0;
  179.     ngens = discgrp->gens->num_el;
  180.     metric = discgrp->attributes & DG_METRIC_BITS;
  181.     bzero(dgel.word, sizeof(dgel.word));
  182.     dgel.attributes = discgrp->attributes;
  183.     TmIdentity(dgel.tform);
  184.     dgel.color = white;
  185.     mydg = discgrp;
  186.  
  187.     init_out_stack();
  188.     get_matrices();
  189.     if (mydg->fsa) enumerate(mydg->fsa->start, 0, &dgel);
  190.     else dumb_enumerate(0,&dgel);
  191.  
  192.     /* clean up the mess */
  193.     delete_list();
  194.  
  195.     enum_list->num_el = enumgetsize();
  196.     enum_list->el_list = enumgetstack();
  197.  
  198.     if (mydg->flag & DG_DEBUG)    {
  199.     fprintf(stderr,"%d elements printed \n",print_cnt);
  200.     fprintf(stderr,"%d elements stored \n",store_cnt);
  201.     fprintf(stderr,"%d elements move too far \n",far_cnt);
  202.     fprintf(stderr,"%d elements too long \n",long_cnt);
  203.     fprintf(stderr,"%d elements duplicates \n",same_cnt);
  204.     }
  205.     return(enum_list);
  206. }
  207.  
  208.  
  209. static void
  210. get_matrices()
  211. {
  212.     int i;
  213.     
  214.     for (i=0; i<mydg->gens->num_el; ++i)
  215.         {
  216.         symbollist[i] = mydg->gens->el_list[i].word[0];
  217.         TmCopy(mydg->gens->el_list[i].tform, mlist[i]);
  218.         }
  219.     fprintf(stderr,"%d generators read\n",i);
  220. }
  221.  
  222.